This disclosure relates generally to exception handling in a data processing system and more specifically to a managed runtime percolation of a condition from a native environment in the data processing system.
Operating systems provide models and application programming interfaces to enable software applications to handle exceptional conditions. Such exceptional conditions may be asynchronous, for example, an interruption requested from an operator console, or synchronous, for example, an attempted execution of an illegal instruction by a portion of the software application or other code associated with the operation of the software application.
General models of condition handling supported by different operating systems include a POSIX® signal handling mechanism, whereby signal handlers are registered process-wide as used in a UNIX® operating system and a stack-based condition/exception handling, as provided in a Microsoft® Windows® and an IBM® z/OS® Language Environment® whereby handlers are registered for a specific stack frame on a stack associated with a particular thread and invoked in a LIFO order.
Managed runtimes, such as the Java® Virtual Machine, leverage host operating system condition handling mechanism as well as integrate with native code (e.g. C, C++ or assembly modules) that may also leverage the host operating system condition handling. When an operating system provides stack-based condition handling, upon notification of a condition, a condition handler may choose to terminate the process; continue execution from the point of interruption, as if the condition had not occurred; continue execution at an arbitrary location; or percolate the condition to allow other condition handlers in the stack a chance to respond to the condition.
Multi-threaded managed runtimes maintain runtime state information on a native stack and may evaluate managed code using a separate execution stack. For example, an implementation of a Java Virtual Machine maintains runtime state information in a single native stack frame per call-in to Java. The one or more Java stack frames are described on a separate native stack.
A crash typically occurs in computing in a computing environment when hardware or software in the form of a program (for example, an application, portion of an application or operating system), ceases to function correctly. The failing program that crashed often exits after encountering a severe error or may cease to function and exhibit a state that is described as a freeze or hang until a diagnostic reporting service documents details of the respective crash.
When a crash occurs in a native environment associated with a native stack frame, resulting in a condition in a native code portion, a most recently registered native handler will handle the condition. The condition handler in the managed runtime frame, a Java frame in the current example, is not aware of the condition and is not affected.
In another example, when the crash occurs in one native stack frame and is handled by a condition handler in a lower stack frame, the lower condition handler can resume execution in the original frame that experienced the crash. However in this scenario, it is not certain the handler will resume execution in the original frame or some other stack frame.
A first solution is to terminate the process when an unexpected native exception or condition is detected by the managed runtime (for example, a SEGFAULT in code that is not managed by the runtime). This solution, for example, is implemented by a Microsoft Common Language Runtime. A second alternative solution also terminates the managed runtime, but without terminating the native operating system process, and performs a cleanup and restart of the managed runtime.
A limitation of the described solutions is a localized problem in native code (for example, an unhandled divide-by-zero) results in a termination of the entire process rather than a single particular thread experiencing the exception. Similarly, a technique of another example results in a termination of the entire managed runtime rather than a single thread. In a multi-tenant environment, implementation of either described solution typically results in a sudden termination of many unrelated applications or processes.
When a failure occurs causing a condition in a native environment and the described solutions terminate the managed runtime, there is also a loss of all potential diagnostic information, as well as interruption of other concurrent processes in the previously running managed environment.